/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.start.model;

import business.service.MongoDbFactory;
import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import com.star.common.PostData;
import com.star.common.Re_Post_NewsCate_Data;
import com.star.common.Re_Post_Profile_Data;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.regex.Pattern;
import org.apache.log4j.Logger;
import org.bson.types.ObjectId;

/**
 *
 * @author ngotandieu
 */
public class PostModel {

    private static final String POST_COLLECTION = "post";
    private static final Logger logger = Logger.getLogger(PostModel.class);
    private static final Lock createLock_ = new ReentrantLock();
    private static PostModel _instance = null;
    private static final DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");

    public static final String CACHE_POST_LIST = "csm_post_list_";
    public static List<String> ALL_CACHE_POST_LIST = new LinkedList<>();
    public static final String ALL_CACHE_POST_LIST_KEY = "csm_all_cache_post_list";
    private static final int CACHE_TIME = 24 * 60 *60;
    
    
    public static PostModel getInstance() {
        if (_instance == null) {
            createLock_.lock();
            try {
                if (_instance == null) {
                    _instance = new PostModel();

                }
            } finally {
                createLock_.unlock();
            }
        }
        return _instance;
    }

    public PostModel() {
        try {
        } catch (Exception ex) {
            logger.error("PostModel: " + ex);
        }
    }

//    public List<PostData> getPost(String pid, int start, int limit) {
//        List<PostData> lstPost = null;
//        try {
//            BasicDBObject basicDBObject = new BasicDBObject("time", -1);
//            DB db = MongoDbFactory.getConnection();
//            DBCollection coll = db.getCollection(POST_COLLECTION);
//            DBCursor cursor = coll.find(new BasicDBObject("pid", pid)).sort(basicDBObject);
//
//            if (limit != -1) {
//                cursor = cursor.skip(start).limit(limit);
//            }
//
//            lstPost = new ArrayList<>();
//            while (cursor.hasNext()) {
//                DBObject dbObject = cursor.next();
//                String objectId = ((ObjectId) dbObject.get("_id")).toString();
//                String title = (String) dbObject.get("title");
//                String slug = (String) dbObject.get("slug");
//                String desc = (String) dbObject.get("desc");
//                String content = (String) dbObject.get("content");
//                int status = (int) dbObject.get("status");
//                String editor = (String) dbObject.get("editor");
//                String author = (String) dbObject.get("author");
//                long updated = (long) dbObject.get("updated");
//                long created = (long) dbObject.get("created");
//                long time = (long) dbObject.get("time");
//                
//                PostData postData = new PostData(pid, objectId, title, slug, desc, content, author, editor, updated, created, status, time);
//                lstPost.add(postData);
//            }
//        } catch (Exception ex) {
//            logger.error("PostModel.getPost: " + ex.getMessage(), ex);
//        }
//        return lstPost;
//    }

    
    public List<PostData> getPost(int start, int limit) {
//        String key = CACHE_POST_LIST + start + limit;
//        Object value = MemcachedModel.getCache(key);
//        if(value != null){
//            return (List<PostData>)value;
//        }
               
        List<PostData> lstPost = null;
        try {
            BasicDBObject basicDBObject = new BasicDBObject("created", -1);
            DB db = MongoDbFactory.getConnection();
            DBCollection coll = db.getCollection(POST_COLLECTION);
            DBCursor cursor = coll.find().sort(basicDBObject);

            if (limit != -1) {
                cursor = cursor.skip(start).limit(limit);
            }

            lstPost = new ArrayList<>();
            while (cursor.hasNext()) {
                DBObject dbObject = cursor.next();
                String objectId = ((ObjectId) dbObject.get("_id")).toString();
                String title = (String) dbObject.get("title");
                String slug = (String) dbObject.get("slug");
                String desc = (String) dbObject.get("desc");
                String content = (String) dbObject.get("content");
                int status = (int) dbObject.get("status");
                String editor = (String) dbObject.get("editor");
                String author = (String) dbObject.get("author");
                long updated = (long) dbObject.get("updated");
                long created = (long) dbObject.get("created");
                long published = (long) (dbObject.get("published") == null ? 0L : dbObject.get("published"));                
                String site = (String) dbObject.get("site"); 
                String thumbFb = (String) dbObject.get("thumbFb"); 
                String tags = (String) dbObject.get("tags");
                String authorNews = (String) dbObject.get("authorNews");
                PostData postData = new PostData(objectId, title, slug, desc, content, author, editor, 
                        updated, created, status, published, site, thumbFb, tags, authorNews);
                lstPost.add(postData);
            }
        } catch (Exception ex) {
            logger.error("PostModel.getPost: " + ex.getMessage(), ex);
        }
                
//        MemcachedModel.setCache(key, lstPost, CACHE_TIME);
//        ALL_CACHE_POST_LIST = MemcachedModel.getListKey(ALL_CACHE_POST_LIST_KEY);
//        ALL_CACHE_POST_LIST.add(key);
//        MemcachedModel.setListKey(ALL_CACHE_POST_LIST_KEY, ALL_CACHE_POST_LIST, CACHE_TIME);        
        return lstPost;
    }
    
    
    
    public List<PostData> getPost(int start, int limit, String id_Search, String pid_Se, String userSearch, 
            String titleSearch, String statusSearch, String created_Se, String cate) {
        List<PostData> lstPost = null;
        try {
            BasicDBObject basicDBObject = new BasicDBObject("created", -1);            
            BasicDBObject query = new BasicDBObject();
            if(!titleSearch.equals("")){
                Pattern regex = Pattern.compile(titleSearch, Pattern.CASE_INSENSITIVE); 
                query.put("title", regex);
            }           
            if(!id_Search.equals(""))
                query.append("_id", new ObjectId(id_Search));
            if(!userSearch.equals(""))
                query.append("author", userSearch);
            if(!statusSearch.equals(""))
                query.append("status", Integer.parseInt(statusSearch));
//            if(!pid_Se.equals(""))
//                query.append("pid", pid_Se);
             
            DB db = MongoDbFactory.getConnection();
            DBCollection coll = db.getCollection(POST_COLLECTION);
            DBCursor cursor = coll.find(query).sort(basicDBObject);
            if (limit != -1) {
                cursor = cursor.skip(start).limit(limit);
            }
            lstPost = new ArrayList<>();  
            Re_Post_NewsCate_Model modelRe = Re_Post_NewsCate_Model.getInstance();
            Re_Post_Profile_Model modelRePostProfile = Re_Post_Profile_Model.getInstance();
            while (cursor.hasNext()) {
                DBObject dbObject = cursor.next();
                String objectId = ((ObjectId) dbObject.get("_id")).toString();                
                String title = (String) dbObject.get("title");
                String slug = (String) dbObject.get("slug");
                String desc = (String) dbObject.get("desc");
                String content = (String) dbObject.get("content");
                int status = (int) dbObject.get("status");                
                long published = (long) (dbObject.get("published") == null ? 0L : dbObject.get("published"));                
                String author = (String) dbObject.get("author");
                String editor = (String) dbObject.get("editor");
                long updated = (long) dbObject.get("updated");
                long created = (long) dbObject.get("created"); 
                String site = (String) dbObject.get("site");  
                String thumbFb = (String) dbObject.get("thumbFb");  
                String tags = (String) dbObject.get("tags");
                String authorNews = (String) dbObject.get("authorNews");
                PostData postData = new PostData(objectId, title, slug, desc, content, author, 
                        editor, updated, created, status, published, site, thumbFb, tags, authorNews);
                
                if(!created_Se.equals("")){
                    Date dateCreated = formatter.parse(created_Se);
                    Date d = new Date(created); 
                    if(d.getDate() != dateCreated.getDate() || d.getMonth() != dateCreated.getMonth()
                            || d.getYear() != dateCreated.getYear()){
                        continue;
                    }                            
                }               
                
                
                boolean testProfile = pid_Se.equals("") ? true : false;
                List<Re_Post_Profile_Data> listProfileOfPost = modelRePostProfile.getItemsByPostId(objectId);
                if(!pid_Se.equals("")){
                    for(Re_Post_Profile_Data item : listProfileOfPost){
                        if(item.getIdProfile().equals(pid_Se)){
                            testProfile = true;
                            break;
                        }
                    }
                }
                
                if(testProfile == true){
                    boolean testCate = cate.equals("") ? true : false;
                    List<Re_Post_NewsCate_Data> listOfCurrentNews = modelRe.getItemsByPostId(objectId);
                    if(!cate.equals("")){
                        for(Re_Post_NewsCate_Data item : listOfCurrentNews){ 
                            if(item.getIdNewsCate().equals(cate)){
                                testCate = true; 
                                break;
                            }                                
                        }
                    }

                    if(testCate == true)
                        lstPost.add(postData);
                }     
            }
        } catch (Exception ex) {
            logger.error("PostModel.getPost: " + ex.getMessage(), ex);
        }
        return lstPost;
    }
    
    
    
    
    public PostData getPostById(String id) {
        try {
            BasicDBObject basicDBObject = new BasicDBObject("_id", new ObjectId(id));
            DB db = MongoDbFactory.getConnection();
            DBCollection coll = db.getCollection(POST_COLLECTION);
            DBCursor cursor = coll.find(basicDBObject);
            if (cursor.hasNext()) {
                DBObject dbObject = cursor.next();                
                String objectId = ((ObjectId) dbObject.get("_id")).toString();
                String title = (String) dbObject.get("title");
                String slug = (String) dbObject.get("slug");
                String desc = (String) dbObject.get("desc");
                String content = (String) dbObject.get("content");
                int status = (int) dbObject.get("status");
                String editor = (String) dbObject.get("editor");
                String author = (String) dbObject.get("author");
                long updated = (long) dbObject.get("updated");
                long created = (long) dbObject.get("created");
                long published = (long) (dbObject.get("published") == null ? 0L : dbObject.get("published"));
                String site = (String) dbObject.get("site");  
                String thumbFb = (String) dbObject.get("thumbFb"); 
                String tags = (String) dbObject.get("tags");
                String authorNews = (String) dbObject.get("authorNews");
                PostData postData = new PostData(objectId, title, slug, desc, content, author, 
                        editor, updated, created, status, published, site, thumbFb, tags, authorNews);
                return postData;
            }
        } catch (Exception ex) {
            logger.error("PostModel.getPostById: " + ex.getMessage(), ex);
            return null;
        }
        return null;
    }

//    public long getPostCount(String pid) {
//        long count = 0;
//        try {
//            DB db = MongoDbFactory.getConnection();
//            DBCollection coll = db.getCollection(POST_COLLECTION);
//            count = coll.getCount(new BasicDBObject("pid", pid));
//        } catch (Exception ex) {
//            logger.error("PostModel.getPostCount: " + ex.getMessage(), ex);
//        }
//        return count;
//    }

    public boolean deletePost(String id) {
        try {
            DB db = MongoDbFactory.getConnection();
            DBCollection coll = db.getCollection(POST_COLLECTION);
            coll.remove(new BasicDBObject("_id", new ObjectId(id)));
            return true;
        } catch (Exception ex) {
            logger.error("PostModel.deletePost: " + ex.getMessage(), ex);
        }
        return false;
    }
    
    public String addNewPost(PostData postData) {
        String id = "";
        try {
            BasicDBObject basicDBObject = new BasicDBObject()                    
                    .append("title", postData.getTitle())
                    .append("slug", postData.getSlug())
                    .append("desc", postData.getDesc())
                    .append("content", postData.getContent())
                    .append("status", postData.getStatus())
                    .append("published", postData.getPublished())
                    .append("editor", postData.getAuthor())
                    .append("author", postData.getAuthor())
                    .append("updated", System.currentTimeMillis())
                    .append("created", System.currentTimeMillis())
                    .append("site", postData.getSite())
                    .append("thumbFb", postData.getThumbFb())
                    .append("tags", postData.getTags())
                    .append("authorNews", postData.getAuthorNews());
            DB db = MongoDbFactory.getConnection();
            DBCollection coll = db.getCollection(POST_COLLECTION);
            coll.insert(basicDBObject);
            
            ObjectId objectId = (ObjectId)basicDBObject.get( "_id" );
            id = objectId.toString();
        } catch (Exception ex) {
            logger.error("PostModel.addPost: " + ex.getMessage(), ex);
        }
        return id;
    }
    
    public boolean updatePost(PostData postData) {
        try {
            BasicDBObject basicDBObject = new BasicDBObject()                    
                    .append("title", postData.getTitle())
                    .append("slug", postData.getSlug())
                    .append("desc", postData.getDesc())
                    .append("content", postData.getContent())
                    .append("status", postData.getStatus())
                    .append("published", postData.getPublished())
                    .append("editor", postData.getEditor())
                    .append("updated", System.currentTimeMillis())
                    .append("site", postData.getSite())
                    .append("thumbFb", postData.getThumbFb());

            DB db = MongoDbFactory.getConnection();
            DBCollection coll = db.getCollection(POST_COLLECTION);
            
            BasicDBObject updateDBObject = new BasicDBObject("$set", basicDBObject);
            BasicDBObject searchDBQuery = new BasicDBObject("_id", new ObjectId(postData.getId()));
            coll.update(searchDBQuery, updateDBObject);
            return true;
        } catch (Exception ex) {
            logger.error("PostModel.updatePost: " + ex.getMessage());
        }
        return false;
    }

//    public List<PostData> getRelatedPost(String pid, String id, int start, int limit) {
//        List<PostData> lstPost = null;
//        try {
//            BasicDBObject basicDBObject = new BasicDBObject("time", -1);
//            DB db = MongoDbFactory.getConnection();
//            DBCollection coll = db.getCollection(POST_COLLECTION);            
//            
//            BasicDBObject queryDBObject = new BasicDBObject("pid", pid);
//            if (!id.equalsIgnoreCase("")) {
//                ObjectId objectId = new ObjectId(id);
//                int timestamp = objectId.getTimestamp();
//                queryDBObject.append("created", new BasicDBObject("$gt", timestamp));
//            }
//            DBCursor cursor = coll.find(queryDBObject).sort(basicDBObject);
//
//            if (limit != -1) {
//                cursor = cursor.skip(start).limit(limit);
//            }
//
//            lstPost = new ArrayList<>();
//            while (cursor.hasNext()) {
//                DBObject dbObject = cursor.next();
//                String objectId = ((ObjectId) dbObject.get("_id")).toString();
//                String title = (String) dbObject.get("title");
//                String slug = (String) dbObject.get("slug");
//                String desc = (String) dbObject.get("desc");
//                String content = (String) dbObject.get("content");
//                int status = (int) dbObject.get("status");
//                long time = (long) dbObject.get("time");
//                String editor = (String) dbObject.get("editor");
//                String author = (String) dbObject.get("author");
//                long updated = (long) dbObject.get("updated");
//                long created = (long) dbObject.get("created");
//                String source = (String) dbObject.get("source");  
//                String image = (String) dbObject.get("image"); 
//                String tags = (String) dbObject.get("tags");
//                String authorNews = (String) dbObject.get("authorNews");
//                PostData postData = new PostData(objectId, title, slug, desc, content, 
//                        author, editor, updated, created, status, time, source, image, tags, authorNews);
//                lstPost.add(postData);
//            }
//        } catch (Exception ex) {
//            logger.error("PostModel.getRelatedPost: " + ex.getMessage(), ex);
//        }
//        return lstPost;
//    }
}
